import RouterViewBox from './sections/RouterViewBox'
import ErrorPage from './components/ErrorPage'
import AsyncComponent from './components/AsyncComponent'
import MainPage from './pages/main'

export const lazyload = page => {
  return resolve => {
    import(/* webpackChunkName: "[request]" */ `@pages/${page}/index.vue`).then(
      mod => {
        resolve(mod)
      }
    )
  }
}

export const convertRoutesToVueRoutes = rootRoutes => {
  const vueRoutes = []
  const createNewRoute = route => {
    let routeObj = {
      path: route.path,
      meta: {
        title: route.title || route.name || '',
        roles: route.roles || null,
        hidden: route.hidden || false,
        activeMenu: route.activeMenu || null,
        jumpLink: route.jumpLink || null,
        needLogin: route.needLogin || false
      },
      name: route.name || route.componentName || route.title || null,
      component: route.componentName
        ? lazyload(route.componentName)
        : route.component
        ? route.component
        : RouterViewBox
    }
    if (route.children) {
      routeObj.children = []
      for (let item of route.children) {
        routeObj.children.push(createNewRoute(item))
      }
    }
    return routeObj
  }
  for (let item of rootRoutes) {
    vueRoutes.push(createNewRoute(item))
  }
  return vueRoutes
}

const commonRoutes = () => [
  {
    path: '/401',
    name: '401',
    component: ErrorPage
  },
  {
    path: '/403',
    name: '403',
    component: ErrorPage
  },
  {
    path: '/500',
    name: '500',
    component: ErrorPage
  },
  {
    path: '*',
    name: '404',
    component: ErrorPage
  }
]

const addRoutesToMainPage = (routes = []) => {
  return [
    {
      path: '/',
      name: 'mainPage',
      meta: {
        root: true
      },
      component: MainPage,
      children: routes
    }
  ]
}

export const generatorVueRoutes = (isInitAsyncRoute, type, routes) => {
  let vueRoutes = []
  if (isInitAsyncRoute) {
    vueRoutes.push({
      path: '*',
      name: 'asyncComponent',
      needLogin: true,
      component: AsyncComponent
    })
  } else {
    switch (type) {
      case 'app':
        vueRoutes = [...routes, ...commonRoutes()]
        break
      case 'layout':
        vueRoutes = [...addRoutesToMainPage(routes), ...commonRoutes()]
        break
    }
  }
  return convertRoutesToVueRoutes(vueRoutes)
}

export const createVueRouter = (VueRouter, routes, mode, base) =>
  new VueRouter({
    mode,
    base,
    scrollBehavior(to, from, savedPosition) {
      if (savedPosition) {
        return savedPosition
      } else {
        return { x: 0, y: 0 }
      }
    },
    routes
  })

export const initVueRoutes = (Vue, async, type, routes) => {
  if (async) {
    Vue.prototype.$isSuccessFetchAsyncRoutes = false
  }
  return generatorVueRoutes(async, type, routes)
}

export const resetVueRouter = (Vue, router, type, routes = [], mode, base) => {
  const newVueRoutes = generatorVueRoutes(false, type, routes)
  const newVueRouter = createVueRouter(VueRouter, newVueRoutes, mode, base)
  router.matcher = newVueRouter.matcher
  router._routes = routes
  Vue.$isSuccessFetchAsyncRoutes = true
}

export const isIntoRouteNeedLogin = intoRoute => {
  return intoRoute.meta.needLogin
}

export const isGetLoginUser = store => {
  const { sn } = store.state.user
  return !!sn
}

export const fetchLoginUserAndSystemsByAppId = (store, appId) =>
  Promise.all([
    store.dispatch('app/setAppId', appId),
    store.dispatch('user/fetchLoginUser', appId),
    store.dispatch('app/fetchSystemsByAppId', appId)
  ])

export const fetchAsyncRoutes = async (store, appId) => {
  return await store.dispatch('app/fetchAsyncRoutes', appId)
}

export const isAuthentication = (vueRouter, into) => {
  const { roles } = into.meta
  // 判断是否需要鉴权验证
  if (Array.isArray(roles) && roles.length) {
    // 获取当前用户权限
    const { role } = vueRouter.app.$options.store.state.user
    // 鉴权验证通过
    if (role && roles.includes(role)) {
      return true
    }
    return false
  }
  return true
}
